package wholemusic.web.watch;

import org.springframework.http.HttpHeaders;

import java.awt.*;
import java.awt.image.BufferedImage;

public class StickWatchPrivate {
    private final static int SCREEN_WIDTH = 160;
    private final static int SCREEN_HEIGHT = 80;

    public static byte[] convertToWatchBitmap() {
        final int totalPixels = SCREEN_WIDTH * SCREEN_HEIGHT;
        final int bufferSize = totalPixels * 3;  // RGB888
        byte[] buffer = new byte[bufferSize];
        for (int y = 0; y < SCREEN_HEIGHT; y++) {
            for (int x = 0; x < SCREEN_WIDTH; x++) {
                final int offset = 3 * (y * SCREEN_WIDTH + x);
                buffer[offset] = (byte) (0xff * x / SCREEN_WIDTH);
                buffer[offset + 1] = 0;
                buffer[offset + 2] = 0;
            }
        }
        return buffer;
    }

    private static byte[] convertToWatchBitmap(BufferedImage image) {
        final int totalPixels = image.getWidth() * image.getHeight();
        final int bufferSize = totalPixels * 3;  // RGB888
        byte[] buffer = new byte[bufferSize];
        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                final int offset = 3 * (y * image.getWidth() + x);
                int rgb = image.getRGB(x, y);
                buffer[offset] = (byte) ((rgb >> 16) & 0xff);
                buffer[offset + 1] = (byte) ((rgb >> 8) & 0xff);
                buffer[offset + 2] = (byte) (rgb & 0xff);
            }
        }
        System.err.printf("data size: %d\n", buffer.length);
        return buffer;
    }

    public static byte[] convertToWatchBitmap(BufferedImage image, HttpHeaders headers) {
        if (image != null) {
            int width = image.getWidth();
            int height = image.getHeight();
            System.err.printf("origin: width=%d, height=%d\n", width, height);
            if (width > SCREEN_WIDTH || height > SCREEN_HEIGHT) {
                final float ratio = (float) width / height;
                System.err.printf("ratio=%f\n", ratio);
                if (ratio > (float) SCREEN_WIDTH / SCREEN_HEIGHT) {
                    System.err.println("case 1");
                    width = SCREEN_WIDTH;
                    height = (int) (SCREEN_WIDTH / ratio);
                } else {
                    System.err.println("case 2");
                    height = SCREEN_HEIGHT;
                    width = (int) (SCREEN_HEIGHT * ratio);
                }
            }
            System.err.printf("scaled: width=%d, height=%d\n", width, height);
            BufferedImage scaled = getScaledImage(image, width, height);
            headers.set("X-Image-Width", String.valueOf(scaled.getWidth()));
            headers.set("X-Image-Height", String.valueOf(scaled.getHeight()));
            headers.set("X-Image-X", String.valueOf((SCREEN_WIDTH - scaled.getWidth()) / 2));
            headers.set("X-Image-Y", String.valueOf((SCREEN_HEIGHT - scaled.getHeight()) / 2));
            return convertToWatchBitmap(scaled);
        }
        return null;
    }

    private static BufferedImage getScaledImage(Image srcImg, int w, int h) {

        //Create a new image with good size that contains or might contain arbitrary alpha values between and including 0.0 and 1.0.
        BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TRANSLUCENT);

        //Create a device-independant object to draw the resized image
        Graphics2D g2 = resizedImg.createGraphics();

        //This could be changed, Cf. http://stackoverflow.com/documentation/java/5482/creating-images-programmatically/19498/specifying-image-rendering-quality
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        //Finally draw the source image in the Graphics2D with the desired size.
        g2.drawImage(srcImg, 0, 0, w, h, null);

        //Disposes of this graphics context and releases any system resources that it is using
        g2.dispose();

        //Return the image used to create the Graphics2D
        return resizedImg;
    }
}
